﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web.Mvc;
using PaceR.Web.MvcModels;
using PaceR.Core.Interfaces;
using PaceR.Web.WebUtilities;
using System.Web.UI;

namespace PaceR.Web.WebExtensions
{
    public static class MvcExtensions
    {
        public static string GetMvcFieldNameFor<TModel, TProperty>(this ModelBindingContext bindingContext, Expression<Func<TModel, TProperty>> expression)
        {
            return ExpressionHelper.GetExpressionText((LambdaExpression)expression);
        }

        public static string GetMvcFieldValueFor<TModel, TProperty>(this ModelBindingContext bindingContext, Expression<Func<TModel, TProperty>> expression)
        {
            var t = bindingContext.ModelName;
            string name = bindingContext.GetMvcFieldNameFor(expression);
            return bindingContext.GetMvcFieldValue(name);
        }

        public static string GetMvcFieldValue(this ModelBindingContext bindingContext, string fieldName)
        {
            var result = bindingContext.ValueProvider.GetValue(fieldName);
            if (result != null) return result.AttemptedValue;
            return null;
        }

        public static object GetMvcFieldRawValue(this ModelBindingContext bindingContext, string fieldName)
        {
            var result = bindingContext.ValueProvider.GetValue(fieldName);
            if (result != null) return result.RawValue;
            return null;
        }

        public static MvcHtmlString MvcCommandFor<TModel>(this HtmlHelper<TModel> html, string commandName, string commandArgument = null, string displayText = null, object htmlAttributes = null)
        {
            if (string.IsNullOrEmpty(displayText)) displayText = commandName;
            if (string.IsNullOrEmpty(commandArgument))
            {
                //if no argument then use the Html field prefix of the View data
                commandArgument = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
                //if no prefix then just use the display text
                if (string.IsNullOrEmpty(commandArgument)) commandArgument = displayText;
            }
            var command = new MvcCommand() { CommandName = commandName, CommandArgument = commandArgument };
            var tagBuilder = new TagBuilder("input");
            tagBuilder.Attributes.Add("type", "submit");
            tagBuilder.Attributes.Add("name", command.ToString());
            tagBuilder.Attributes.Add("value", displayText);

            if (htmlAttributes != null)
            {
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                tagBuilder.MergeAttributes(attributes, true);
            }

            return new MvcHtmlString(tagBuilder.ToString());
        }

        public static MvcHtmlString RenderMessages(this HtmlHelper html, IResultMessages messages, string cssClass = null)
        {
            var renderer = HtmlRendererFactoryUtil.Factory.GetMessageRenderer();
            StringBuilder sb = new StringBuilder();
            HtmlTextWriter writer = new HtmlTextWriter(new System.IO.StringWriter(sb));


            //errors
            if (messages.ErrorMessages.Count() > 0)
                renderer.RenderMessages(writer, messages.ErrorMessages, cssClass, ResultMessageTypes.Error);
            //warnings
            if (messages.WarningMessages.Count() > 0)
                renderer.RenderMessages(writer, messages.WarningMessages, cssClass, ResultMessageTypes.Warning);
            //Info
            if (messages.InformationMessages.Count() > 0)
                renderer.RenderMessages(writer, messages.InformationMessages, cssClass, ResultMessageTypes.Information);

            return new MvcHtmlString(sb.ToString());
        }

        public static MvcScript BeginScript(this HtmlHelper htmlHelper)
        {
            MvcScript.BeginScript(htmlHelper.ViewContext);
            return new MvcScript(htmlHelper.ViewContext);
        }

        public static void EndScript(this HtmlHelper htmlHelper)
        {
            MvcScript.EndScript(htmlHelper.ViewContext);
        }
    }
}
